import { isEmpty } from './util'
 
export default class Cache {
  
  _dataMap = {}

  constructor (options) {
    this.options = Object.assign({
      idField: 'id'
    }, options)
  }

  concat (data) {
    if (!data || !data.length) {
      return
    }
    data.forEach(v => {
      if (v[this.options.idField]) {
        this._dataMap[v[this.options.idField]] = v
      }
    })
  }

  add (data) {
    if (!data || !data[this.options.idField]) {
      return
    }
    this._dataMap[this.options.idField] = data
  }

  del (id) {
    delete this._dataMap[id]
  }

  clear () {
    this._dataMap = {}
  }

  get (id) {
    return this._dataMap[id]
  }

  fetch (checkValue, fetchFn) {
    if (checkValue && !Array.isArray(checkValue)) {
      checkValue = [checkValue]
    } else if (!checkValue) {
      checkValue = []
    }
    const ps = new Promise((resolve, reject) => {
      let rs = []
      const ids = checkValue.reduce((ids, v) => {
        if (isEmpty(v)) {
          return ids
        }
        if (typeof v === 'object') {
          rs.push(v)
        } else {
          const cache = this.get(v)
          if (cache) {
            rs.push(cache)
          } else {
            ids.push(v)
          }
        }
        return ids
      }, [])
      if (ids.length) {
        fetchFn(ids).then(data => {
          if (data && data.length) {
            rs = [].concat(rs, data)
          }
          resolve(rs)
        }, reject)
      } else {
        resolve(rs)
      }
    })
    ps.then(rs => {
      this.concat(rs)
    })
    return ps
  }
}
